<?php
/**
 * Created by PhpStorm.
 * Script Name: Mp.php
 * Create: 12/26/22 7:18 PM
 * Description:
 * Author: fudaoji<fdj@kuryun.cn>
 */

namespace plugin\wechat\app\tenant\controller;

use app\common\constant\Common;
use app\common\service\Qrcode as QrcodeService;
use EasyOpen\Tencent\Client as TencentCli;
use EasyOpen\Tencent\Request\Mp\ComponentFastregisterweapp;
use plugin\wechat\app\model\Mini as MiniM;
use plugin\wechat\app\service\OpenPlatform as OpenPlatformService;
use plugin\wechat\app\TenantController;
use app\common\service\Tenant as TenantService;
use plugin\wechat\app\service\Common as CommonService;
use plugin\wechat\app\service\Mini as MiniService;
use plugin\wechat\app\service\MiniReg as RegService;
use Support\Request;
use plugin\wechat\app\service\Setting as SettingService;

class Mini extends TenantController
{
    /**
     * @var MiniM
     */
    protected $model;
    /**
     * @var TencentCli
     */
    private TencentCli $client;

    public function __construct(){
        parent::__construct();
        $this->model = new MiniM();
        $this->client = new TencentCli();
        $this->insertTenantId = true;
    }

    private function tabList(){
        return [
            'mini' => ['title' => '已有账号', 'href' => url('mini/index')],
            'reg' => ['title' => '注册记录', 'href' => url('minireg/index')]
        ];
    }

    /**
     * 代注册
     * @param Request $request
     * @return mixed|\support\Response
     * Author: fudaoji<fdj@kuryun.cn>
     * @throws \EasyWeChat\Kernel\Exceptions\HttpException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \Exception
     */
    public function fastReg(Request $request){
        if(request()->isPost()){
            $post_data = input('post.');
            $res = $this->validate($post_data,'\\plugin\\wechat\\app\\validate\\MiniReg.add');
            if($res !== true){
                return $this->error($res, '', ['token' => token()]);
            }
            $res = OpenPlatformService::registerMiniprogram($post_data);
            if($res !== true) {
                return $this->error('微信返回错误：'.$res, '', ['token' => token()]);
            }
            $post_data['company_id'] = TenantService::getCompanyId();
            $post_data['tenant_id'] = $this->tenantInfo('id');
            RegService::reg($post_data);
            return $this->success('提交成功，请法人留意微信消息，继续完成认证！', '');
        }

        $builder = new FormBuilder();
        $builder->setTip('认真填写以下信息，即可快速完成小程序注册！')
            ->addFormItem('name', 'text', '企业名称', '需与工商部门登记信息一致', [], 'required')
            ->addFormItem('code', 'text', '企业代码', '填写企业代码', [], 'required')
            ->addFormItem('code_type', 'select', '企业代码类型', '企业代码类型', RegService::codeTypes(), 'required')
            ->addFormItem('legal_persona_wechat', 'text', '法人微信号', '填写法人微信号，注意不是昵称', [], 'required')
            ->addFormItem('legal_persona_name', 'text', '法人姓名', '注意和开户银行保持一致',[], 'required')
            ->addFormItem('component_phone', 'number', '第三方联系电话', '请填写手机号');
        return $builder->show();
    }

    /**
     * 手动添加
     * @param Request $request
     * @return mixed|\support\Response
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function add(Request $request){
        if(request()->isPost()){
            $post_data = input('post.');
            $res = $this->validate($post_data,'\\plugin\\wechat\\app\\validate\\Mini.add');
            if($res !== true){
                return $this->error($res, '', ['token' => token()]);
            }
            $post_data['is_auth'] = 1;
            return parent::savePost($request, '', $post_data);
        }
        $builder = new FormBuilder();
        $builder->addFormItem('nick_name', 'text', '小程序名称', '不超过30字', [], 'required maxlength=30')
            ->addFormItem('appid', 'text', 'APPID', 'appID', [], 'required')
            ->addFormItem('appsecret', 'text', 'APPSecret', 'APPSecret', [], 'required')
            ->addFormItem('signature', 'textarea', '小程序描述', '版本描述', [], 'maxlength=200')
            ->addFormItem('verify_type_info', 'select', '认证', '认证', MiniService::verifyTypes(), 'required')
            ->addFormItem('user_name', 'text', '原始ID', '原始ID')
            ->addFormItem('head_img', 'picture_url', '头像', '头像')
            ->addFormItem('qrcode_url', 'picture_url', '小程序码', '小程序码')
            ->addFormItem('verify_file', 'file_to_root', '校验文件', '校验文件');
        return $builder->show();
    }

    public function index(){
        if(request()->isPost()){
            $post_data = input('post.');
            $where = [
                ['company_id', '=', TenantService::getCompanyId()]
            ];
            !empty($post_data['search_key']) && $where[] = ['alias|nick_name', 'like', '%'.$post_data['search_key'].'%'];

            $query = $this->model->where($where);
            $total = $query->count();
            if ($total) {
                $list = $query->page($post_data['page'], $post_data['limit'])
                    ->order('update_time', 'desc')
                    ->select();
            } else {
                $list = [];
            }

            return $this->success('success', '', ['total' => $total, 'list' => $list]);
        }

        $builder = new ListBuilder();
        $builder->setSearch([
            ['type' => 'text', 'name' => 'search_key', 'title' => '搜索词','placeholder' => '微信号或昵称']
        ])
            ->setTabNav($this->tabList(), 'mini')
            ->addTopButton('addnew',['href' => url('choose'), 'text' => '绑定小程序'])
            ->addTableColumn(['title' => '序号', 'type' => 'index', 'minWidth' => 70])
            ->addTableColumn(['title' => '头像', 'field' => 'head_img', 'type' => 'picture','minWidth' => 100])
            ->addTableColumn(['title' => '昵称', 'field' => 'nick_name', 'minWidth' => 100])
            ->addTableColumn(['title' => 'AppId', 'field' => 'appid', 'minWidth' => 100])
            ->addTableColumn(['title' => '接入状态', 'field' => 'is_auth', 'type' => 'enum', 'options' => CommonService::platformStatus()])
            ->addTableColumn(['title' => '状态', 'field' => 'status', 'type' => 'switch', 'options' => Common::status()])
            ->addTableColumn(['title' => '操作', 'minWidth' => 130, 'type' => 'toolbar'])
            ->addRightButton('edit', ['href' => url('info', ['id' => '__data_id__']),'title' => '管理设置', 'text' => '管理设置'])
            ->addRightButton('delete');
        return $builder->show();
    }

    /**
     * 管理设置
     * @return mixed
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function info(){
        $id = input('id', 0);
        if(! $mp_info = $this->model->find($id)){
            return $this->error('数据不存在!');
        }
        $mp_info['type_desc'] = MiniService::getTypeDesc($mp_info);
        $assign = ['mp' => $mp_info, 'auth_url' => $this->getAuthUrl()];
        return $this->show($assign);
    }

    /**
     * 公众号授权
     * @author fudaoji<fdj@kuryun.cn>
     */
    private function getAuthUrl() {
        try {
            $redirect_url = request()->domain() . url('authCallback');
            $url = OpenPlatformService::getOpenPlatform()->getPreAuthorizationUrl($redirect_url);
        }catch (\Exception $e){
            $url = '';
        }
        return $url;
    }


    /**
     * 选择添加方式
     * @return mixed
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function choose(){
        /*$config = SettingService::getSettings('default_app');
        $wap_url = \request()->domain()."/app/wechat/wap/index/index?appid=".($config['mp_appid'] ?? '')."&tenant=" . $this->tenantInfo('id');*/
        $assign = [
            'auth_url' => $this->getAuthUrl(),
            //'fast_reg_h5' => QrcodeService::generateCode($wap_url)
        ];
        return $this->show($assign);
    }

    /**
     * 小程序授权回调
     * @param Request $request
     * @return \support\Response
     * @throws \Psr\SimpleCache\InvalidArgumentException
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function authCallback(Request $request) {
        try {
            // 在用户在授权页授权流程完成后，授权页会自动跳转进入回调URI，并在URL参数中返回授权码和过期时间，如：(https://easywechat.com/callback?auth_code=xxx&expires_in=600)
            $handleAuthorize = OpenPlatformService::getOpenPlatform()->handleAuthorize($request->get('auth_code'));
            $appId = $handleAuthorize['authorization_info']['authorizer_appid'];
            // 获取授权方的帐号基本信息
            $authorizer_info = OpenPlatformService::getOpenPlatform()->getAuthorizer($appId);
            MiniService::updateAuthInfo($authorizer_info, TenantService::getCompanyId(), $this->tenantInfo('id'));
            return $this->redirect('/app/wechat/tenant#//app/wechat/tenant/mini/index');
        } catch (\Exception $e){
            dao_log()->error($e->getMessage());
            return $this->error('授权回调处理错误!');
        }
    }
}